//===============================================================================
// Microsoft patterns & practices
// Web Client Software Factory
//-------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//-------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WCSFContrib.PageFlow.Xml.Tests.Mocks;
using WCSFContrib.PageFlow;

namespace WCSFContrib.PageFlow.Xml.Tests
{
   [TestClass]
    public class XmlPageFlowFactoryFixture
    {
        private static IDictionary<string, NavigationGraph> _navigationGraphs;

       [ClassInitialize]
        public static void SetUp(TestContext testContext)
        {
            _navigationGraphs = new Dictionary<string, NavigationGraph>();
            NavigationGraph navigationGraphUnconstrained = new MockUnconstrainedXmlPageFlowNavigationGraph();
            NavigationGraph navigationGraphConstrained = new MockConstrainedXmlPageFlowNavigationGraph();

            _navigationGraphs.Add(navigationGraphUnconstrained.PageFlowType.AssemblyQualifiedName, navigationGraphUnconstrained);
            _navigationGraphs.Add(navigationGraphConstrained.PageFlowType.AssemblyQualifiedName, navigationGraphConstrained);
        }

        [TestMethod]
        public void GetPageflowByTypeCreatesNewInstance()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));
                Assert.IsNotNull(pageflow);
            }
        }

        [TestMethod]
        public void GetPageflowByTypeCreatesDifferentInstancesEachTime()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));
                IPageFlow pageflow2 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));

                Assert.AreNotSame(pageflow1, pageflow2);
                Assert.AreNotEqual(pageflow1, pageflow2);
            }
        }

        [TestMethod]
        public void GetPageflowByTypeAndThenByIdCreatesEqualInstances()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));
                IPageFlow pageflow2 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow), pageflow1.Id);

                Assert.AreNotSame(pageflow1, pageflow2);
                Assert.AreEqual(pageflow1, pageflow2);
            }
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void GetPageFlowWithInvalidInstanceIdThrows()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow), Guid.NewGuid());
            }
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void GetPageFlowWithExistingInstanceIdAndDifferentPageFlowTypeThrows()
        {
            IPageFlow pageflow1 = null;
            IPageFlow pageflow2 = null;
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));
            }

            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                pageflow2 = factory.GetPageFlow(typeof(MockConstrainedPageFlow), pageflow1.Id);
            }
        }

        [TestMethod]
        public void GetPageflowByTypeAndThenByIdCreatesEqualInstancesAndDifferentFactoriesIntances()
        {
            IPageFlow pageflow1 = null;
            IPageFlow pageflow2 = null;
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));
            }

            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                pageflow2 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow), pageflow1.Id);
            }

            Assert.AreNotSame(pageflow1, pageflow2);
            Assert.AreEqual(pageflow1, pageflow2);
        }

        [TestMethod]
        public void GetPageFlowWithInstanceIdPreservesPageFlowProperties()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));

                pageflow1.Start();
                pageflow1.SetCurrentPage("pageB");

                IPageFlow pageflow2 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow), pageflow1.Id);

                Assert.AreEqual(pageflow1.Status, pageflow2.Status);
                Assert.AreEqual(pageflow1.CurrentPage, pageflow2.CurrentPage);
                Assert.AreEqual(pageflow1.Transitions.Count, pageflow2.Transitions.Count);
            }
        }

        [TestMethod]
        public void GetPageFlowWithInstanceIdPreservesPageFlowUserData()
        {
            using (XmlPageFlowFactory factory = new XmlPageFlowFactory(_navigationGraphs, new MockNavigationService()))
            {
                IPageFlow pageflow1 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow));

                pageflow1.Start();
                pageflow1.UserData["TestData"] = new object();

                IPageFlow pageflow2 = factory.GetPageFlow(typeof(MockUnconstrainedPageFlow), pageflow1.Id);

                Assert.AreEqual(pageflow1.UserData.Keys.Count, pageflow2.UserData.Keys.Count);
                Assert.AreEqual(pageflow1.UserData["TestData"], pageflow2.UserData["TestData"]);
            }
        }
	}    
}
